package org.serverct.finalfight.util;

import com.sun.istack.internal.NotNull;
import org.bukkit.configuration.file.YamlConfiguration;
import org.serverct.finalfight.FinalFight;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;

public class ResourceUtils {
    public static YamlConfiguration autoUpdateConfigs(String path, String fileName) {
        File file = CustomSettings.getFile(path, fileName);
        final InputStream resource = FinalFight.plugin.getResource(path + fileName);
        if (resource != null) {
            if (!file.isFile()) {
                FinalFight.plugin.saveResource(path + fileName, true);
                return YamlConfiguration.loadConfiguration(file);
            }
            try (InputStreamReader reader = new InputStreamReader(resource, StandardCharsets.UTF_8)) {
                try (BufferedReader buffer = new BufferedReader(reader)) {
                    final ArrayDeque<String> strings = buffer.lines().collect(Collectors.toCollection(ArrayDeque::new));
                    Map<String, List<String>> commits = new LinkedHashMap<>();
                    Map<String, List<String>> area = new LinkedHashMap<>();
                    Collection<String> copyright = new ArrayList<>();
                    YamlUpdater.parse(strings, commits, area, copyright);
                    try (RandomAccessFile data = new RandomAccessFile(file, "rw")) {
                        try (InputStreamReader fReader = new InputStreamReader(new InputStream() {
                            @Override
                            public int read() throws IOException {
                                return data.read();
                            }

                            @Override
                            public int read(@NotNull byte[] b) throws IOException {
                                return data.read(b);
                            }

                            @Override
                            public int read(@NotNull byte[] b, int off, int len) throws IOException {
                                return data.read(b, off, len);
                            }
                        }, StandardCharsets.UTF_8)) {
                            try (BufferedReader fBuffer = new BufferedReader(fReader)) {
                                Map<String, List<String>> output_commits = new LinkedHashMap<>();
                                Map<String, List<String>> output_areas = new LinkedHashMap<>();
                                YamlUpdater.parse(fBuffer.lines().collect(Collectors.toCollection(ArrayDeque::new)),
                                        output_commits, output_areas, null);
                                YamlUpdater.merge(commits, area, output_commits, output_areas);
                                commits = output_commits;
                                area = output_areas;
                            }
                        }
                        data.seek(0);
                        try (OutputStreamWriter writer = new OutputStreamWriter(new OutputStream() {
                            @Override
                            public void write(int b) throws IOException {
                                data.write(b);
                            }

                            @Override
                            public void write(@NotNull byte[] b, int off, int len) throws IOException {
                                data.write(b, off, len);
                            }

                            @Override
                            public void write(@NotNull byte[] b) throws IOException {
                                data.write(b);
                            }
                        }, StandardCharsets.UTF_8)) {
                            YamlUpdater.store(commits, area, copyright, writer);
                        }
                        data.setLength(data.getFilePointer());
                    }
                }
            } catch (IOException ioe) {
                FinalFight.plugin.getLogger().log(Level.SEVERE, "更新配置文件失败: " + path + fileName, ioe);
            }
        }
        return YamlConfiguration.loadConfiguration(file);
    }
}
